const my_obj = {
  name: "zyy",
  age: 18,
  habbit: 'read',
  mes: "success",
  date: new Date(),
};

type myType = typeof my_obj;

type GetStrMyType<T> = {
  [K in keyof T]: string;
}

type myTypeStr = GetStrMyType<myType>; // {name: string, age: string, habbit: string}


// 我期望里面的所有key 值驼峰必须加个 get ，而且是函数类型 {getName: (name: string) => string}, getAge: (age: number) => number}, getHabbit: (habbit: string) => string}


type GetStrMyType2<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: (arg: K) => T[K];
}

type myTypeStr2 = GetStrMyType2<myType>;

const myarr = ['zhangsan', 'lisi', 'wangwu', "hello", "mmemem"] as const;

type myArrType = typeof myarr[number]; // 这里得到的是联合类型；"zhangsan" | "lisi" | "wangwu" | "hello" | "mmemem"

type GetObjType<T extends string> = { // T 的每个项都是 string
  [K in T]: string; // K 就是这个联合类型中的每一项
}

type MyArr2Obj = GetObjType<myArrType>;

const aa: MyArr2Obj = {
  zhangsan: "hahah",
  lisi: "xixi",
  wangwu: "wangwu",
  hello: "hello",
  mmemem: "mmemem"
}

// 过滤不需要的属性

interface MyObj {
  name: string;
  age: number;
  habbit: string;
  mes: string;
  date: Date;
  mm: number;
  gg: number;
  xixi: string;
}

type MyDemo = {
  name: string;
  age: number;
  isYanger: boolean;
  xixi: number;
}

type UserOmit = Omit<MyObj, 'age' | 'date'>;

// 把不 string 类型的类型全部过滤掉
type ExcludeNumberAndDate<T extends Object> = {
  [Key in keyof T as T[Key] extends string ? Key : never]: T[Key];
};

type myExclude = ExcludeNumberAndDate<MyObj>;

type myDemoExclude = ExcludeNumberAndDate<MyDemo>;


// 联合类型映射
type S = {
  kind: "square";
  x: number;
  y: number;
};

type C = {
  kind: "circle";
  radius: number;
};

type D = {
  kind: "multiple";
  a: 123,
  b: 33,
  E: number;
};

type MyEvent<T extends { kind: string }> = {
  [Key in T as Key['kind']]: (event: Key) => void;
}

type Config = MyEvent<S | C | D>;

// 等同于
type ConfigMapAfter = {
  square: (event: S) => void;
  circle: (event: C) => void;
};

const MyConfig: Config = {
  square: (event: S) => {
    console.log(event.x);
  },
  circle: (event) => {

    console.log(event.radius);
  },
  multiple: (event) => {
    console.log(event.a);
  }
}


